package com.wondream.rabbitmq.producer;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Produce02_publish {

    private static final String QUEUE_INFORM_EMAIL = "queue_inform_email";
    private static final String QUEUE_INFORM_SMS = "queue_inform_sms";
    private static final String EXCHANGE_FANOUT_INFORM = "exchange_fanout_inform";

    public static void main(String []args){
        // 通过连接工厂创建新的连接和mq建立连接
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        // 设置虚拟目录
        connectionFactory.setVirtualHost("/");
        // 建立新连接
        Connection connection = null;
        Channel channel = null;
        try {
            connection = connectionFactory.newConnection();
            // 创建会话通道channel
            channel = connection.createChannel();
            // 使用默认交换机
            // 声明队列 如果队列在mq中没有则要创建
            // 参数：String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments
            /**
             * 参数说明
             * 1、queue 队列名称
             * 2、durable 是否持久化，如果持久化，mq重启后队列还在
             * 3、exclusive 是否独占连接，队列只允许在该连接中访问，如果连接关闭队列自动删除，如果将此参数设置true可以用于临时队列的创建
             * 4、autoDelete 队列不再使用时自动删除。如果将此参数和exclusive参数设置为true就可以实现临时队列
             * 5、argumens 参数，可以设置一个队列的扩展参数
             */
            channel.queueDeclare(QUEUE_INFORM_EMAIL, true, false, false, null);
            channel.queueDeclare(QUEUE_INFORM_SMS, true, false, false, null);

            // 声明一个交换机
            // 参数：String exchange, String type
            /**
             * 参数明细
             * 1、交换机的名称
             * 2、交换机的类型
             */
            channel.exchangeDeclare(EXCHANGE_FANOUT_INFORM, BuiltinExchangeType.FANOUT);

            // 进行交换机和队列绑定
            // 参数：String queue, String exchange, String routingKey
            /**
             * 参数明细
             * 1、queue 队列名称
             * 2、exchange 交换机名称
             * 3、routingKey 路由key，在发布订阅模式中为空字符串
             */
            channel.queueBind(QUEUE_INFORM_EMAIL, EXCHANGE_FANOUT_INFORM, "");
            channel.queueBind(QUEUE_INFORM_SMS, EXCHANGE_FANOUT_INFORM, "");

            // 发送消息
            // 参数：String exchange, String routingKey, BasicProperties props, byte[] body
            /**
             * 参数明细：
             * 1、exchange 交换机，如果不指定将使用mq的默认交换机
             * 2、routingKey 路由key，交换机根据路由key来将消息转发到指定的队列,如果使用默认交换机，routingKey要设置为队列的名称
             * 3、props 消息的属性
             * 4、body 消息内容
             */
            for (int i=0 ; i < 5 ; i++){
                String messages = "send inform message to user";
                channel.basicPublish(EXCHANGE_FANOUT_INFORM, "", null, messages.getBytes());
                System.out.println("send message to mq:"+messages);
            }

        } catch (Exception e){
            e.printStackTrace();
        } finally {
            try {channel.close(); } catch (Exception e) {}
            try {connection.close(); } catch (Exception e) {}
        }
    }
}
